
package com.hlkj.pay.app.merchant.ext.impl.heepay;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.common.ICommonAppService;
import com.hlkj.pay.app.common.IUploadService;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantAccessExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.access.*;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.FuYouConfig;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.utils.FuYouCallBackParamsParseUtil;
import com.hlkj.pay.app.merchant.ext.impl.heepay.dto.HeePayAccessExtentDto;
import com.hlkj.pay.app.merchant.ext.impl.heepay.dto.HeePayAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.heepay.dto.HeePayConfig;
import com.hlkj.pay.app.merchant.ext.impl.heepay.handler.HeePayMerchantAccessConfigHandler;
import com.hlkj.pay.app.merchant.ext.impl.heepay.handler.HeePayMerchantAccessInfoHandler;
import com.hlkj.pay.dto.merchant.AccessChannelParamsDto;
import com.hlkj.pay.dto.merchant.MerchantAccessDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessAuthDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessBusinessDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessCardDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelDictDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.service.pay.IPayChannelDictService;
import com.hlkj.pay.util.HttpRequestUtil;
import com.hlkj.pay.vo.order.resp.MerchantProductQueryResp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * heepay进件操作
 * 
 * @author HlpayTeam
 * @date 2024/09/26 10:25
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = MerchantExtConstant.CHANNEL_HEEPAY)
public class HeePayMerchantAccessExtPt implements ChannelMerchantAccessExtPt {

    private final HeePayMerchantAccessInfoHandler heePayMerchantAccessInfoHandler;

    private final HeePayMerchantAccessConfigHandler heePayMerchantAccessConfigHandler;

    private final IUploadService uploadService;

    private final ICommonAppService commonAppService;

    private final IPayChannelDictService payChannelDictService;

    @Override
    public void channelConfigCheck(ChannelMerchantAccessCommonContext channelMerchantAccessCommonContext) {
        CommonResult<HeePayConfig> heePayConfigCommonResult = heePayMerchantAccessInfoHandler.heePayConfig(channelMerchantAccessCommonContext.getProviderChannelConfig(),
                channelMerchantAccessCommonContext.isTest());
        if (!heePayConfigCommonResult.isSuccess()) {
            channelMerchantAccessCommonContext.setRemark(heePayConfigCommonResult.getMsg());
            channelMerchantAccessCommonContext.setProcessStatus(false);
        }
    }

    @Override
    public void merchantAccess(ChannelMerchantAccessContext channelMerchantAccessContext) {
        log.info("heepay渠道提交进件 请求参数:{}", JsonUtils.toJsonString(channelMerchantAccessContext));
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessInfo();
        if (StringUtils.hasText(merchantAccessInfo.getSubMchId())) {
            log.info("heepay渠道当前没有更新商户信息直接返回:{}", merchantAccessInfo.getSubMchId());
            return;
        }
        MerchantAccessBusinessDO merchantAccessBusiness = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessBusiness();
        MerchantAccessCardDO merchantAccessCard = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessCard();
        PayChannelDictDO payChannelDictDO = payChannelDictService.queryChannelDict(merchantAccessInfo.getChannelCode(), PayEnums.DICT_KEY.BANK_CODE.getCode(),
                merchantAccessCard.getBankCode());
        if (payChannelDictDO == null) {
            channelMerchantAccessContext.setRemark("银行字典数据错误,请检查");
            channelMerchantAccessContext.setProcessStatus(false);
            return;
        }
        List<PayChannelDictDO> payChannelDictList = new ArrayList<>();
        payChannelDictList.add(payChannelDictDO);
        channelMerchantAccessContext.setPayChannelDictList(payChannelDictList);
        heePayMerchantAccessInfoHandler.merchantAccess(channelMerchantAccessContext);
    }

    @Override
    public String requestUrl(MerchantAccessDto merchantAccessInfoDO) {

        return null;
    }

    @Override
    public String channelParams(AccessChannelParamsDto accessChannelParamsDto) {
        HeePayAppChannelParams params = new HeePayAppChannelParams();
        HeePayAccessExtentDto lakalaAccessExtentDto = JsonUtils.parseObject(accessChannelParamsDto.getExtendA(), HeePayAccessExtentDto.class);
        params.setHeePayId(lakalaAccessExtentDto.getHeePayId());
        params.setCustomerId(lakalaAccessExtentDto.getCustomerId());
        return JsonUtils.toJsonStringNotNull(params);
    }

    @Override
    public void merchantAccessQuery(ChannelMerchantAccessQueryContext channelMerchantAccessQueryContext) {
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantAccessQueryContext.getMerchantAccessInfo();
        if (!StringUtils.hasText(merchantAccessInfoDO.getApplyNo()) && !StringUtils.hasText(merchantAccessInfoDO.getSubMchId())) {
            channelMerchantAccessQueryContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessQueryContext.setRemark("申请单号和商户号不能都为空");
            return;
        }
        heePayMerchantAccessInfoHandler.accessQueryRequest(channelMerchantAccessQueryContext);
    }

    @Override
    public void merchantSign(ChannelMerchantAccessSignContext channelMerchantAccessSignContext) {
        // heepay 签约 在后台 当前不对接
        channelMerchantAccessSignContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.WAIT_SET);
    }

    @Override
    public void merchantSignQuery(ChannelMerchantAccessSignContext channelMerchantAccessSignContext) {

    }

    @Override
    public void merchantBusinessOpen(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo();
        MerchantEnum.CHANNEL_CONFIG_STATUS accessStatus = MerchantEnum.CHANNEL_CONFIG_STATUS.from(merchantAccessInfo.getAuditStatus());
        switch (accessStatus) {
            case AUDIT:
            case AUDITING:
                // 审核中
                ChannelMerchantAccessQueryContext channelMerchantAccessQueryContext = new ChannelMerchantAccessQueryContext();
                channelMerchantAccessQueryContext.setMerchantAccessInfo(channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo());
                channelMerchantAccessQueryContext.setProviderChannelConfig(channelMerchantBusinessContext.getProviderChannelConfig());
                heePayMerchantAccessInfoHandler.accessQueryRequest(channelMerchantAccessQueryContext);
                if (channelMerchantBusinessContext.isProcessStatus()) {
                    channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.SUBMERINFO);
                    channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.WAIT_SET);
                }
            case SUBMERINFO:
                // 审核通过需要查询子商户信息
                heePayMerchantAccessConfigHandler.processSubMerInfoQuery(channelMerchantBusinessContext);
                break;
            default:
        }
    }

    @Override
    public void wechatConfigInit(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 获取子商户信息进行微信参数配置
        channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.WECHAT_AUTH);
    }

    @Override
    public void wechatConfigAdd(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 获取子商户信息进行微信参数配置
        heePayMerchantAccessConfigHandler.processWxConfigSetAdd(channelMerchantBusinessContext);
    }

    @Override
    public void wechatConfigQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        // 微信参数配置查询
        heePayMerchantAccessConfigHandler.processWxConfigQuery(channelMerchantAccessAuthQueryContext);

    }

    @Override
    public void wechatAuthConfig(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 微信参数配置
        // heepay 为自动认证无需处理
        channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.WECHAT_AUTHING);
    }

    @Override
    public boolean authConfigQueryType() {
        return true;
    }

    @Override
    public void wechatAuthQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        // 文件上传完成就是微信参数自动配置
        heePayMerchantAccessConfigHandler.processWxAuthQuery(channelMerchantAccessAuthQueryContext);
        List<MerchantAccessAuthDO> merchantAccessAuthList = channelMerchantAccessAuthQueryContext.getMerchantAccessAuthList();
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantAccessAuthQueryContext.getMerchantAccessInfo();
        if (!CollectionUtils.isEmpty(merchantAccessAuthList)) {
            merchantAccessAuthList.stream().forEach(merchantAccessAuthDO -> {
                merchantAccessAuthDO.setType(1);
                merchantAccessAuthDO.setSn(merchantAccessInfo.getSn());
                merchantAccessAuthDO.setAccessId(merchantAccessInfo.getId());
                if (!StringUtils.hasText(merchantAccessAuthDO.getAuthUrl()) && merchantAccessAuthDO.getQrCodeArray() != null && merchantAccessAuthDO.getQrCodeArray().length > 0) {
                    CommonResult<String> commonResult = uploadService.upload(merchantAccessAuthDO.getQrCodeArray(), CommonEnum.OssEnum.IMAGE);
                    merchantAccessAuthDO.setAuthUrl(commonResult.getData());
                }
            });
        }
        channelMerchantAccessAuthQueryContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.ALIPAY_AUTH);
    }

    @Override
    public void alipayAuthConfig(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 支付宝参数配置
        // heepay 为自动认证无需处理
        channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.ALIPAY_AUTHING);
    }

    @Override
    public void alipayAuthQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        // 文件上传完成就是微信参数自动配置
        heePayMerchantAccessConfigHandler.processAliAuthQuery(channelMerchantAccessAuthQueryContext);
        List<MerchantAccessAuthDO> merchantAccessAuthList = channelMerchantAccessAuthQueryContext.getMerchantAccessAuthList();
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantAccessAuthQueryContext.getMerchantAccessInfo();
        if (!CollectionUtils.isEmpty(merchantAccessAuthList)) {
            merchantAccessAuthList.stream().forEach(merchantAccessAuthDO -> {
                merchantAccessAuthDO.setType(2);
                merchantAccessAuthDO.setSn(merchantAccessInfo.getSn());
                merchantAccessAuthDO.setAccessId(merchantAccessInfo.getId());
            });
        }
        channelMerchantAccessAuthQueryContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.FINISH);
    }

    @Override
    public MerchantAccessCallBackDto accessCallBackParamsParse(HttpServletRequest servletRequest, ProviderChannelConfigDO providerChannelConfigDO) {
        String bodyParams = HttpRequestUtil.requestBodyParams(servletRequest);
        log.info("汇付宝收到商户状态通知:{}", bodyParams);
        Map<String, String> map = JsonUtils.parseObject(bodyParams, Map.class);
        MerchantAccessCallBackDto merchantAccessCallBackDto = new MerchantAccessCallBackDto();
        merchantAccessCallBackDto.setApplyNo(map.get("applyNo"));
        merchantAccessCallBackDto.setSubMchId(map.get("customerId"));
        merchantAccessCallBackDto.setCallBackBody(bodyParams);
        return merchantAccessCallBackDto;
    }

    @Override
    public CommonResult<String> accessCallbackParse(String callBackBody, List<ProviderChannelConfigDO> channelConfigDOList) {
        return null;
    }

    @Override
    public MerchantBusinessCallBackDto businessCallBackParamsParse(String callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        return FuYouCallBackParamsParseUtil.businessCallBackParamsParse(callBackBody);
    }

    @Override
    public boolean verify(String callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        FuYouConfig fuYouConfig = JsonUtils.parseObject(channelConfig, FuYouConfig.class);
        return FuYouCallBackParamsParseUtil.verify(fuYouConfig, callBackBody);
    }

    @Override
    public String callBackResponse(CommonResult commonResult) {
        if (commonResult.isSuccess()) {
            return "ok";
        }
        else {
            return commonResult.getMsg();
        }
    }

    @Override
    public void termAdd(ChannelMerchantTermContext channelMerchantTermContext) {

    }

    @Override
    public void reloadMerchantAuth(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 审核通过需要查询子商户信息
        heePayMerchantAccessConfigHandler.processSubMerInfoQuery(channelMerchantBusinessContext);
    }

    @Override
    public void channelSplit(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 文件上传完成就是微信参数自动配置
        heePayMerchantAccessConfigHandler.channelSplit(channelMerchantBusinessContext);
    }

    @Override
    public void productUpdate(ChannelMerchantBusinessContext channelMerchantBusinessContext) {

    }

    @Override
    public Integer queryMerAuthStatus(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        return null;
    }

    @Override
    public MerchantProductQueryResp productQuery(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        return null;
    }

    @Override
    public MerchantChannelSplitCallBackDto easySplitCallBackParamsParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return null;
    }

}
